﻿using System;
using UnityEngine;
using UnityEngine.Rendering;

namespace UnityStandardAssets.CinematicEffects
{
	// Token: 0x020004CF RID: 1231
	[ExecuteInEditMode]
	[ImageEffectAllowedInSceneView]
	[RequireComponent(typeof(Camera))]
	[AddComponentMenu("Cinematic Image Effects/Screen Space Reflections")]
	public class ScreenSpaceReflection : MonoBehaviour
	{
		// Token: 0x1700020B RID: 523
		// (get) Token: 0x0600191A RID: 6426 RVA: 0x00072A3B File Offset: 0x00070E3B
		public Shader shader
		{
			get
			{
				if (this.m_Shader == null)
				{
					this.m_Shader = Shader.Find("Hidden/ScreenSpaceReflection");
				}
				return this.m_Shader;
			}
		}

		// Token: 0x1700020C RID: 524
		// (get) Token: 0x0600191B RID: 6427 RVA: 0x00072A64 File Offset: 0x00070E64
		public Material material
		{
			get
			{
				if (this.m_Material == null)
				{
					this.m_Material = ImageEffectHelper.CheckShaderAndCreateMaterial(this.shader);
				}
				return this.m_Material;
			}
		}

		// Token: 0x1700020D RID: 525
		// (get) Token: 0x0600191C RID: 6428 RVA: 0x00072A8E File Offset: 0x00070E8E
		public Camera camera_
		{
			get
			{
				if (this.m_Camera == null)
				{
					this.m_Camera = base.GetComponent<Camera>();
				}
				return this.m_Camera;
			}
		}

		// Token: 0x0600191D RID: 6429 RVA: 0x00072AB4 File Offset: 0x00070EB4
		private void OnEnable()
		{
			if (!ImageEffectHelper.IsSupported(this.shader, false, true, this))
			{
				base.enabled = false;
				return;
			}
			this.camera_.depthTextureMode |= DepthTextureMode.Depth;
			ScreenSpaceReflection.kReflectionTextures = new int[5];
			ScreenSpaceReflection.kNormalAndRoughnessTexture = Shader.PropertyToID("_NormalAndRoughnessTexture");
			ScreenSpaceReflection.kHitPointTexture = Shader.PropertyToID("_HitPointTexture");
			ScreenSpaceReflection.kReflectionTextures[0] = Shader.PropertyToID("_ReflectionTexture0");
			ScreenSpaceReflection.kReflectionTextures[1] = Shader.PropertyToID("_ReflectionTexture1");
			ScreenSpaceReflection.kReflectionTextures[2] = Shader.PropertyToID("_ReflectionTexture2");
			ScreenSpaceReflection.kReflectionTextures[3] = Shader.PropertyToID("_ReflectionTexture3");
			ScreenSpaceReflection.kReflectionTextures[4] = Shader.PropertyToID("_ReflectionTexture4");
			ScreenSpaceReflection.kBlurTexture = Shader.PropertyToID("_BlurTexture");
			ScreenSpaceReflection.kFilteredReflections = Shader.PropertyToID("_FilteredReflections");
			ScreenSpaceReflection.kFinalReflectionTexture = Shader.PropertyToID("_FinalReflectionTexture");
			ScreenSpaceReflection.kTempTexture = Shader.PropertyToID("_TempTexture");
		}

		// Token: 0x0600191E RID: 6430 RVA: 0x00072BAC File Offset: 0x00070FAC
		private void OnDisable()
		{
			if (this.m_Material)
			{
				UnityEngine.Object.DestroyImmediate(this.m_Material);
			}
			this.m_Material = null;
			if (this.camera_ != null)
			{
				if (this.m_CommandBuffer != null)
				{
					this.camera_.RemoveCommandBuffer(CameraEvent.AfterFinalPass, this.m_CommandBuffer);
				}
				this.m_CommandBuffer = null;
			}
		}

		// Token: 0x0600191F RID: 6431 RVA: 0x00072C14 File Offset: 0x00071014
		public void OnPreRender()
		{
			if (this.material == null)
			{
				return;
			}
			if (Camera.current.actualRenderingPath != RenderingPath.DeferredShading)
			{
				return;
			}
			int num = (this.settings.reflectionSettings.reflectionQuality != ScreenSpaceReflection.SSRResolution.High) ? 2 : 1;
			int num2 = this.camera_.pixelWidth / num;
			int num3 = this.camera_.pixelHeight / num;
			float num4 = (float)this.camera_.pixelWidth;
			float num5 = (float)this.camera_.pixelHeight;
			float num6 = num4 / 2f;
			float num7 = num5 / 2f;
			RenderTextureFormat format = (!this.camera_.allowHDR) ? RenderTextureFormat.ARGB32 : RenderTextureFormat.ARGBHalf;
			this.material.SetInt("_RayStepSize", this.settings.reflectionSettings.stepSize);
			this.material.SetInt("_AdditiveReflection", (this.settings.reflectionSettings.blendType != ScreenSpaceReflection.SSRReflectionBlendType.Additive) ? 0 : 1);
			this.material.SetInt("_BilateralUpsampling", (!this.bilateralUpsample) ? 0 : 1);
			this.material.SetInt("_TreatBackfaceHitAsMiss", (!this.treatBackfaceHitAsMiss) ? 0 : 1);
			this.material.SetInt("_AllowBackwardsRays", (!this.settings.reflectionSettings.reflectBackfaces) ? 0 : 1);
			this.material.SetInt("_TraceBehindObjects", (!this.traceBehindObjects) ? 0 : 1);
			this.material.SetInt("_MaxSteps", this.settings.reflectionSettings.iterationCount);
			this.material.SetInt("_FullResolutionFiltering", 0);
			this.material.SetInt("_HalfResolution", (this.settings.reflectionSettings.reflectionQuality == ScreenSpaceReflection.SSRResolution.High) ? 0 : 1);
			this.material.SetInt("_HighlightSuppression", (!this.highlightSuppression) ? 0 : 1);
			float value = num4 / (-2f * (float)Math.Tan((double)this.camera_.fieldOfView / 180.0 * 3.141592653589793 * 0.5));
			this.material.SetFloat("_PixelsPerMeterAtOneMeter", value);
			this.material.SetFloat("_ScreenEdgeFading", this.settings.screenEdgeMask.intensity);
			this.material.SetFloat("_ReflectionBlur", this.settings.reflectionSettings.reflectionBlur);
			this.material.SetFloat("_MaxRayTraceDistance", this.settings.reflectionSettings.maxDistance);
			this.material.SetFloat("_FadeDistance", this.settings.intensitySettings.fadeDistance);
			this.material.SetFloat("_LayerThickness", this.settings.reflectionSettings.widthModifier);
			this.material.SetFloat("_SSRMultiplier", this.settings.intensitySettings.reflectionMultiplier);
			this.material.SetFloat("_FresnelFade", this.settings.intensitySettings.fresnelFade);
			this.material.SetFloat("_FresnelFadePower", this.settings.intensitySettings.fresnelFadePower);
			Matrix4x4 projectionMatrix = this.camera_.projectionMatrix;
			Vector4 vector = new Vector4(-2f / (num4 * projectionMatrix[0]), -2f / (num5 * projectionMatrix[5]), (1f - projectionMatrix[2]) / projectionMatrix[0], (1f + projectionMatrix[6]) / projectionMatrix[5]);
			Vector3 v = (!float.IsPositiveInfinity(this.camera_.farClipPlane)) ? new Vector3(this.camera_.nearClipPlane * this.camera_.farClipPlane, this.camera_.nearClipPlane - this.camera_.farClipPlane, this.camera_.farClipPlane) : new Vector3(this.camera_.nearClipPlane, -1f, 1f);
			this.material.SetVector("_ReflectionBufferSize", new Vector2((float)num2, (float)num3));
			this.material.SetVector("_ScreenSize", new Vector2(num4, num5));
			this.material.SetVector("_InvScreenSize", new Vector2(1f / num4, 1f / num5));
			this.material.SetVector("_ProjInfo", vector);
			this.material.SetVector("_CameraClipInfo", v);
			Matrix4x4 lhs = default(Matrix4x4);
			lhs.SetRow(0, new Vector4(num6, 0f, 0f, num6));
			lhs.SetRow(1, new Vector4(0f, num7, 0f, num7));
			lhs.SetRow(2, new Vector4(0f, 0f, 1f, 0f));
			lhs.SetRow(3, new Vector4(0f, 0f, 0f, 1f));
			Matrix4x4 matrix = lhs * projectionMatrix;
			this.material.SetMatrix("_ProjectToPixelMatrix", matrix);
			this.material.SetMatrix("_WorldToCameraMatrix", this.camera_.worldToCameraMatrix);
			this.material.SetMatrix("_CameraToWorldMatrix", this.camera_.worldToCameraMatrix.inverse);
			if (this.m_CommandBuffer == null)
			{
				this.m_CommandBuffer = new CommandBuffer();
				this.m_CommandBuffer.name = "Screen Space Reflections";
				this.m_CommandBuffer.GetTemporaryRT(ScreenSpaceReflection.kNormalAndRoughnessTexture, -1, -1, 0, FilterMode.Point, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear);
				this.m_CommandBuffer.GetTemporaryRT(ScreenSpaceReflection.kHitPointTexture, num2, num3, 0, FilterMode.Bilinear, RenderTextureFormat.ARGBHalf, RenderTextureReadWrite.Linear);
				for (int i = 0; i < 5; i++)
				{
					this.m_CommandBuffer.GetTemporaryRT(ScreenSpaceReflection.kReflectionTextures[i], num2 >> i, num3 >> i, 0, FilterMode.Bilinear, format);
				}
				this.m_CommandBuffer.GetTemporaryRT(ScreenSpaceReflection.kFilteredReflections, num2, num3, 0, (!this.bilateralUpsample) ? FilterMode.Bilinear : FilterMode.Point, format);
				this.m_CommandBuffer.GetTemporaryRT(ScreenSpaceReflection.kFinalReflectionTexture, num2, num3, 0, FilterMode.Point, format);
				this.m_CommandBuffer.Blit(BuiltinRenderTextureType.CameraTarget, ScreenSpaceReflection.kNormalAndRoughnessTexture, this.material, 6);
				this.m_CommandBuffer.Blit(BuiltinRenderTextureType.CameraTarget, ScreenSpaceReflection.kHitPointTexture, this.material, 0);
				this.m_CommandBuffer.Blit(BuiltinRenderTextureType.CameraTarget, ScreenSpaceReflection.kFilteredReflections, this.material, 5);
				this.m_CommandBuffer.Blit(ScreenSpaceReflection.kFilteredReflections, ScreenSpaceReflection.kReflectionTextures[0], this.material, 8);
				for (int j = 1; j < 5; j++)
				{
					int nameID = ScreenSpaceReflection.kReflectionTextures[j - 1];
					int num8 = j;
					this.m_CommandBuffer.GetTemporaryRT(ScreenSpaceReflection.kBlurTexture, num2 >> num8, num3 >> num8, 0, FilterMode.Bilinear, format);
					this.m_CommandBuffer.SetGlobalVector("_Axis", new Vector4(1f, 0f, 0f, 0f));
					this.m_CommandBuffer.SetGlobalFloat("_CurrentMipLevel", (float)j - 1f);
					this.m_CommandBuffer.Blit(nameID, ScreenSpaceReflection.kBlurTexture, this.material, 2);
					this.m_CommandBuffer.SetGlobalVector("_Axis", new Vector4(0f, 1f, 0f, 0f));
					nameID = ScreenSpaceReflection.kReflectionTextures[j];
					this.m_CommandBuffer.Blit(ScreenSpaceReflection.kBlurTexture, nameID, this.material, 2);
					this.m_CommandBuffer.ReleaseTemporaryRT(ScreenSpaceReflection.kBlurTexture);
				}
				this.m_CommandBuffer.Blit(ScreenSpaceReflection.kReflectionTextures[0], ScreenSpaceReflection.kFinalReflectionTexture, this.material, 3);
				this.m_CommandBuffer.GetTemporaryRT(ScreenSpaceReflection.kTempTexture, this.camera_.pixelWidth, this.camera_.pixelHeight, 0, FilterMode.Bilinear, format);
				this.m_CommandBuffer.Blit(BuiltinRenderTextureType.CameraTarget, ScreenSpaceReflection.kTempTexture, this.material, 1);
				this.m_CommandBuffer.Blit(ScreenSpaceReflection.kTempTexture, BuiltinRenderTextureType.CameraTarget);
				this.m_CommandBuffer.ReleaseTemporaryRT(ScreenSpaceReflection.kTempTexture);
				this.camera_.AddCommandBuffer(CameraEvent.AfterFinalPass, this.m_CommandBuffer);
			}
		}

		// Token: 0x0400100B RID: 4107
		[SerializeField]
		public ScreenSpaceReflection.SSRSettings settings = ScreenSpaceReflection.SSRSettings.defaultSettings;

		// Token: 0x0400100C RID: 4108
		[Tooltip("Enable to limit the effect a few bright pixels can have on rougher surfaces")]
		private bool highlightSuppression;

		// Token: 0x0400100D RID: 4109
		[Tooltip("Enable to allow rays to pass behind objects. This can lead to more screen-space reflections, but the reflections are more likely to be wrong.")]
		private bool traceBehindObjects = true;

		// Token: 0x0400100E RID: 4110
		[Tooltip("Enable to force more surfaces to use reflection probes if you see streaks on the sides of objects or bad reflections of their backs.")]
		private bool treatBackfaceHitAsMiss;

		// Token: 0x0400100F RID: 4111
		[Tooltip("Drastically improves reflection reconstruction quality at the expense of some performance.")]
		private bool bilateralUpsample = true;

		// Token: 0x04001010 RID: 4112
		[SerializeField]
		private Shader m_Shader;

		// Token: 0x04001011 RID: 4113
		private Material m_Material;

		// Token: 0x04001012 RID: 4114
		private Camera m_Camera;

		// Token: 0x04001013 RID: 4115
		private CommandBuffer m_CommandBuffer;

		// Token: 0x04001014 RID: 4116
		private static int kNormalAndRoughnessTexture;

		// Token: 0x04001015 RID: 4117
		private static int kHitPointTexture;

		// Token: 0x04001016 RID: 4118
		private static int[] kReflectionTextures;

		// Token: 0x04001017 RID: 4119
		private static int kFilteredReflections;

		// Token: 0x04001018 RID: 4120
		private static int kBlurTexture;

		// Token: 0x04001019 RID: 4121
		private static int kFinalReflectionTexture;

		// Token: 0x0400101A RID: 4122
		private static int kTempTexture;

		// Token: 0x020004D0 RID: 1232
		public enum SSRResolution
		{
			// Token: 0x0400101C RID: 4124
			High,
			// Token: 0x0400101D RID: 4125
			Low = 2
		}

		// Token: 0x020004D1 RID: 1233
		public enum SSRReflectionBlendType
		{
			// Token: 0x0400101F RID: 4127
			PhysicallyBased,
			// Token: 0x04001020 RID: 4128
			Additive
		}

		// Token: 0x020004D2 RID: 1234
		[Serializable]
		public struct SSRSettings
		{
			// Token: 0x1700020E RID: 526
			// (get) Token: 0x06001920 RID: 6432 RVA: 0x000734CD File Offset: 0x000718CD
			public static ScreenSpaceReflection.SSRSettings defaultSettings
			{
				get
				{
					return ScreenSpaceReflection.SSRSettings.s_Default;
				}
			}

			// Token: 0x04001021 RID: 4129
			[ScreenSpaceReflection.SSRSettings.LayoutAttribute]
			public ScreenSpaceReflection.ReflectionSettings reflectionSettings;

			// Token: 0x04001022 RID: 4130
			[ScreenSpaceReflection.SSRSettings.LayoutAttribute]
			public ScreenSpaceReflection.IntensitySettings intensitySettings;

			// Token: 0x04001023 RID: 4131
			[ScreenSpaceReflection.SSRSettings.LayoutAttribute]
			public ScreenSpaceReflection.ScreenEdgeMask screenEdgeMask;

			// Token: 0x04001024 RID: 4132
			private static readonly ScreenSpaceReflection.SSRSettings s_Default = new ScreenSpaceReflection.SSRSettings
			{
				reflectionSettings = new ScreenSpaceReflection.ReflectionSettings
				{
					blendType = ScreenSpaceReflection.SSRReflectionBlendType.PhysicallyBased,
					reflectionQuality = ScreenSpaceReflection.SSRResolution.High,
					maxDistance = 100f,
					iterationCount = 256,
					stepSize = 3,
					widthModifier = 0.5f,
					reflectionBlur = 1f,
					reflectBackfaces = true
				},
				intensitySettings = new ScreenSpaceReflection.IntensitySettings
				{
					reflectionMultiplier = 1f,
					fadeDistance = 100f,
					fresnelFade = 1f,
					fresnelFadePower = 1f
				},
				screenEdgeMask = new ScreenSpaceReflection.ScreenEdgeMask
				{
					intensity = 0.03f
				}
			};

			// Token: 0x020004D3 RID: 1235
			[AttributeUsage(AttributeTargets.Field)]
			public class LayoutAttribute : PropertyAttribute
			{
			}
		}

		// Token: 0x020004D4 RID: 1236
		[Serializable]
		public struct IntensitySettings
		{
			// Token: 0x04001025 RID: 4133
			[Tooltip("Nonphysical multiplier for the SSR reflections. 1.0 is physically based.")]
			[Range(0f, 2f)]
			public float reflectionMultiplier;

			// Token: 0x04001026 RID: 4134
			[Tooltip("How far away from the maxDistance to begin fading SSR.")]
			[Range(0f, 1000f)]
			public float fadeDistance;

			// Token: 0x04001027 RID: 4135
			[Tooltip("Amplify Fresnel fade out. Increase if floor reflections look good close to the surface and bad farther 'under' the floor.")]
			[Range(0f, 1f)]
			public float fresnelFade;

			// Token: 0x04001028 RID: 4136
			[Tooltip("Higher values correspond to a faster Fresnel fade as the reflection changes from the grazing angle.")]
			[Range(0.1f, 10f)]
			public float fresnelFadePower;
		}

		// Token: 0x020004D5 RID: 1237
		[Serializable]
		public struct ReflectionSettings
		{
			// Token: 0x04001029 RID: 4137
			[Tooltip("How the reflections are blended into the render.")]
			public ScreenSpaceReflection.SSRReflectionBlendType blendType;

			// Token: 0x0400102A RID: 4138
			[Tooltip("Half resolution SSRR is much faster, but less accurate.")]
			public ScreenSpaceReflection.SSRResolution reflectionQuality;

			// Token: 0x0400102B RID: 4139
			[Tooltip("Maximum reflection distance in world units.")]
			[Range(0.1f, 300f)]
			public float maxDistance;

			// Token: 0x0400102C RID: 4140
			[Tooltip("Max raytracing length.")]
			[Range(16f, 1024f)]
			public int iterationCount;

			// Token: 0x0400102D RID: 4141
			[Tooltip("Log base 2 of ray tracing coarse step size. Higher traces farther, lower gives better quality silhouettes.")]
			[Range(1f, 16f)]
			public int stepSize;

			// Token: 0x0400102E RID: 4142
			[Tooltip("Typical thickness of columns, walls, furniture, and other objects that reflection rays might pass behind.")]
			[Range(0.01f, 10f)]
			public float widthModifier;

			// Token: 0x0400102F RID: 4143
			[Tooltip("Blurriness of reflections.")]
			[Range(0.1f, 8f)]
			public float reflectionBlur;

			// Token: 0x04001030 RID: 4144
			[Tooltip("Enable for a performance gain in scenes where most glossy objects are horizontal, like floors, water, and tables. Leave on for scenes with glossy vertical objects.")]
			public bool reflectBackfaces;
		}

		// Token: 0x020004D6 RID: 1238
		[Serializable]
		public struct ScreenEdgeMask
		{
			// Token: 0x04001031 RID: 4145
			[Tooltip("Higher = fade out SSRR near the edge of the screen so that reflections don't pop under camera motion.")]
			[Range(0f, 1f)]
			public float intensity;
		}

		// Token: 0x020004D7 RID: 1239
		private enum PassIndex
		{
			// Token: 0x04001033 RID: 4147
			RayTraceStep,
			// Token: 0x04001034 RID: 4148
			CompositeFinal,
			// Token: 0x04001035 RID: 4149
			Blur,
			// Token: 0x04001036 RID: 4150
			CompositeSSR,
			// Token: 0x04001037 RID: 4151
			MinMipGeneration,
			// Token: 0x04001038 RID: 4152
			HitPointToReflections,
			// Token: 0x04001039 RID: 4153
			BilateralKeyPack,
			// Token: 0x0400103A RID: 4154
			BlitDepthAsCSZ,
			// Token: 0x0400103B RID: 4155
			PoissonBlur
		}
	}
}
